{ "cells": [ { "cell_type": "markdown", "id": "f2a6d772", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Improved Quadratic Equation Solver" ] }, { "cell_type": "markdown", "id": "90807e9d", "metadata": { "slideshow": { "slide_type": "-" }, "tags": [ "remove-cell" ] }, "source": [ "**CS1302 Introduction to Computer Programming**\n", "___" ] }, { "cell_type": "markdown", "id": "c090b397", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "In this notebook, we will improve the quadratic equation solver in the previous lab using conditional executions. \n", "First of all, run the following to setup the environment." ] }, { "cell_type": "code", "execution_count": 1, "id": "947b618f", "metadata": { "slideshow": { "slide_type": "skip" } }, "outputs": [], "source": [ "from ipywidgets import interact\n", "import math\n", "import numpy as np" ] }, { "cell_type": "markdown", "id": "6eb68c8c", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## Discriminant" ] }, { "cell_type": "markdown", "id": "7db9c46b", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "Recall that a quadratic equation is\n", "\n", "$$\n", "ax^2+bx+c=0\n", "$$\n", "\n", "where $a$, $b$, and $c$ are real-valued coefficients, and $x$ is the unknown variable." ] }, { "cell_type": "markdown", "id": "57cdc489", "metadata": {}, "source": [ "````{prf:definition} Discriminant\n", "\n", "The disciminant of a quadratic equation is defined as\n", "\n", "$$\n", "\\Delta := b^2 - 4ac.\n", "$$ (discriminant)\n", "\n", "````" ] }, { "cell_type": "markdown", "id": "a682a686", "metadata": {}, "source": [ "The discriminant $\\Delta$ discriminates the roots $\\frac{-b\\pm \\sqrt{\\Delta}}{2a}$ of a quadratic equation:" ] }, { "cell_type": "markdown", "id": "2654072e", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "````{prf:proposition} \n", "\n", "The roots of a quadratic equation {eq}`quadratic` are the same (repeated) equal to $-\\frac{b}{2a}$ when the discriminant is zero, i.e., $\\Delta=0$.\n", "\n", "````" ] }, { "cell_type": "markdown", "id": "35ce4c61", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "**Exercise** Complete the following function by assigning `roots` only one root when the discriminant is zero. E.g., if $(a,b,c)=(1,-2,1)$, then `roots` should be assigned the value `1.0` instead of `1.0, 1.0`." ] }, { "cell_type": "code", "execution_count": 2, "id": "5d5f7ec5", "metadata": { "deletable": false, "nbgrader": { "cell_type": "code", "checksum": "ab6fbcdff876e3cfc8767e7377284ccb", "grade": false, "grade_id": "zero_determininant", "locked": false, "schema_version": 3, "solution": true, "task": false }, "slideshow": { "slide_type": "fragment" }, "tags": [ "remove-output" ] }, "outputs": [], "source": [ "def get_roots(a, b, c):\n", " d = b ** 2 - 4 * a * c # discriminant\n", " if math.isclose(d, 0):\n", " # YOUR CODE HERE\n", " raise NotImplementedError()\n", " return roots" ] }, { "cell_type": "markdown", "id": "bc790249", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "````{hint}\n", "\n", "Consider using the [if statement](https://docs.python.org/3/reference/compound_stmts.html#if) as follows:\n", "\n", "```Python\n", "def get_roots(a, b, c):\n", " d = b ** 2 - 4 * a * c # discriminant\n", " if math.isclose(d, 0):\n", " roots = ___ # repeated root\n", " else:\n", " d **= 0.5\n", " roots = ___, ___\n", " return roots\n", "```\n", "\n", "This is a solution template where `___` needs to be filled in with appropriate code. If you have a more efficient/simpler implementation, you need *not* follow the solution template. E.g., to challenge your understanding of short-circuit evaluation, you can write your solution using boolean operations without any if statement.\n", "\n", "````" ] }, { "cell_type": "code", "execution_count": 3, "id": "9c3cf252", "metadata": { "code_folding": [ 0 ], "deletable": false, "editable": false, "nbgrader": { "cell_type": "code", "checksum": "16860060eb7229216c52e0e6c7e96484", "grade": true, "grade_id": "test-zero_determinant", "locked": true, "points": 1, "schema_version": 3, "solution": false, "task": false }, "tags": [ "hide-input", "remove-output" ] }, "outputs": [ { "ename": "NameError", "evalue": "name 'roots' is not defined", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 14\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 15\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 16\u001b[0;31m \u001b[0mtest_get_roots\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0;36m1.0\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m0.0\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 17\u001b[0m \u001b[0mtest_get_roots\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m0.0\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m\u001b[0m in \u001b[0;36mtest_get_roots\u001b[0;34m(roots, a, b, c)\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mc\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mreal\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mc\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mimag\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 6\u001b[0;31m \u001b[0mroots_\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mget_roots\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mb\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mc\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 7\u001b[0m assert (\n\u001b[1;32m 8\u001b[0m \u001b[0mhasattr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mroots\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m\"__len__\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m\u001b[0m in \u001b[0;36mget_roots\u001b[0;34m(a, b, c)\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0;31m# YOUR CODE HERE\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0;32mraise\u001b[0m \u001b[0mNotImplementedError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 6\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mroots\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mNameError\u001b[0m: name 'roots' is not defined" ] } ], "source": [ "# tests\n", "def test_get_roots(roots, a, b, c):\n", " def mysort(c):\n", " return c.real, c.imag\n", "\n", " roots_ = get_roots(a, b, c)\n", " assert (\n", " hasattr(roots, \"__len__\")\n", " and np.isclose(\n", " sorted(list(roots), key=mysort), sorted(list(roots_), key=mysort)\n", " ).all()\n", " or roots == roots_ or np.isclose(roots, roots_)\n", " )\n", "\n", "\n", "test_get_roots((-1.0, 0.0), 1, 1, 0)\n", "test_get_roots(0.0, 1, 0, 0)" ] }, { "cell_type": "code", "execution_count": 4, "id": "c8e24bc2", "metadata": { "code_folding": [ 0 ], "deletable": false, "editable": false, "nbgrader": { "cell_type": "code", "checksum": "ea74289e50129048beb923088ce499c8", "grade": true, "grade_id": "hidden_test-zero_determinant", "locked": true, "points": 1, "schema_version": 3, "solution": false, "task": false }, "tags": [ "remove-cell" ] }, "outputs": [], "source": [ "# hidden tests" ] }, { "cell_type": "markdown", "id": "4f7aa15e", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "**Exercise** Why use `math.isclose(d, 0)` instead of `d == 0`?" ] }, { "cell_type": "markdown", "id": "21bf7b7a", "metadata": { "deletable": false, "nbgrader": { "cell_type": "markdown", "checksum": "12889805830e3af64988ae0de141f1b7", "grade": true, "grade_id": "isclose", "locked": false, "points": 1, "schema_version": 3, "solution": true, "task": false }, "slideshow": { "slide_type": "fragment" } }, "source": [ "YOUR ANSWER HERE" ] }, { "cell_type": "markdown", "id": "1338a121", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Linear equation" ] }, { "cell_type": "markdown", "id": "2f50e4e2", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "If $a=0$, the earlier formula for the roots are invalid due to division by zero. Nevertheless, the equation remains valid:\n", "\n", "$$\n", "bx + c=0.\n", "$$" ] }, { "cell_type": "markdown", "id": "14b834b0", "metadata": {}, "source": [ "**Exercise** Improve the function `get_roots` to return the root $-\\frac{c}{b}$ when $a=0$." ] }, { "cell_type": "code", "execution_count": 5, "id": "06935007", "metadata": { "deletable": false, "nbgrader": { "cell_type": "code", "checksum": "790fe0b27e9e6efe7e54afa74e32dbad", "grade": false, "grade_id": "linear", "locked": false, "schema_version": 3, "solution": true, "task": false }, "tags": [ "remove-output" ] }, "outputs": [], "source": [ "def get_roots(a, b, c):\n", " d = b ** 2 - 4 * a * c\n", " # YOUR CODE HERE\n", " raise NotImplementedError()\n", " return roots" ] }, { "cell_type": "markdown", "id": "83dc5b7c", "metadata": {}, "source": [ "````{hint} \n", "\n", "Solution template:\n", "```Python\n", "def get_roots(a, b, c):\n", " d = b ** 2 - 4 * a * c # discriminant\n", " if ___:\n", " roots = ___\n", " elif math.isclose(d, 0):\n", " roots = ___ # repeated root\n", " else:\n", " d **= 0.5\n", " roots = ___\n", " return roots\n", "```\n", "\n", "````" ] }, { "cell_type": "code", "execution_count": 6, "id": "81c78d2d", "metadata": { "code_folding": [], "deletable": false, "editable": false, "nbgrader": { "cell_type": "code", "checksum": "5c1bddf43ef773f22d90ffad549ccc45", "grade": true, "grade_id": "test-linear", "locked": true, "points": 1, "schema_version": 3, "solution": false, "task": false }, "tags": [ "remove-output", "hide-input" ] }, "outputs": [ { "ename": "NotImplementedError", "evalue": "", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mNotImplementedError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;31m# tests\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0mtest_get_roots\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0;36m1.0\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m-\u001b[0m\u001b[0;36m0.0\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 3\u001b[0m \u001b[0mtest_get_roots\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m0.0\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0mtest_get_roots\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m0.5\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m-\u001b[0m\u001b[0;36m2\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m\u001b[0m in \u001b[0;36mtest_get_roots\u001b[0;34m(roots, a, b, c)\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mc\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mreal\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mc\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mimag\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 6\u001b[0;31m \u001b[0mroots_\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mget_roots\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mb\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mc\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 7\u001b[0m assert (\n\u001b[1;32m 8\u001b[0m \u001b[0mhasattr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mroots\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m\"__len__\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m\u001b[0m in \u001b[0;36mget_roots\u001b[0;34m(a, b, c)\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0md\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mb\u001b[0m \u001b[0;34m**\u001b[0m \u001b[0;36m2\u001b[0m \u001b[0;34m-\u001b[0m \u001b[0;36m4\u001b[0m \u001b[0;34m*\u001b[0m \u001b[0ma\u001b[0m \u001b[0;34m*\u001b[0m \u001b[0mc\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0;31m# YOUR CODE HERE\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 4\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mNotImplementedError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 5\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mroots\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;31mNotImplementedError\u001b[0m: " ] } ], "source": [ "# tests\n", "test_get_roots((-1.0, -0.0), 1, 1, 0)\n", "test_get_roots(0.0, 1, 0, 0)\n", "test_get_roots(0.5, 0, -2, 1)" ] }, { "cell_type": "code", "execution_count": 7, "id": "0acfdccb", "metadata": { "code_folding": [ 0 ], "deletable": false, "editable": false, "nbgrader": { "cell_type": "code", "checksum": "0b77d8b49baaccd677119a45a0a2a230", "grade": true, "grade_id": "hidden_test-linear", "locked": true, "points": 1, "schema_version": 3, "solution": false, "task": false }, "tags": [ "remove-cell" ] }, "outputs": [], "source": [ "# hidden tests" ] }, { "cell_type": "markdown", "id": "b79e5149", "metadata": {}, "source": [ "## Degenerate cases" ] }, { "cell_type": "markdown", "id": "5791fbf9", "metadata": {}, "source": [ "What if $a=b=0$? In that case, the equation becomes\n", "\n", "$$\n", "c = 0\n", "$$\n", "which is always satisfied if $c=0$ but never satisfied if $c\\neq 0$." ] }, { "cell_type": "markdown", "id": "0ff6b07d", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "**Exercise** Improve the function `get_roots` to return root(s) under all cases:\n", "- If $a=0$ and $b\\neq 0$, assign `roots` to the single root $-\\frac{c}{b}$. \n", "- If $a=b=0$ and $c\\neq 0$, assign `roots` to `None`. \n", " Note that `None` is an object, not a string.\n", "- If $a=b=c=0$, there are infinitely many roots. Assign to `roots` the tuple `-float('inf'), float('inf')`. \n", " Note that `float('inf')` converts the string `'inf'` to a floating point value that represents $\\infty$." ] }, { "cell_type": "code", "execution_count": 8, "id": "d37bac31", "metadata": { "deletable": false, "nbgrader": { "cell_type": "code", "checksum": "474f601f43c279d150f959b1672c2f86", "grade": false, "grade_id": "degenerate", "locked": false, "schema_version": 3, "solution": true, "task": false }, "slideshow": { "slide_type": "skip" }, "tags": [ "remove-output" ] }, "outputs": [], "source": [ "def get_roots(a, b, c):\n", " d = b ** 2 - 4 * a * c\n", " # YOUR CODE HERE\n", " raise NotImplementedError()\n", " return roots" ] }, { "cell_type": "markdown", "id": "6b3467af", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "````{hint} \n", "\n", "Use nested `if` statements as in the solution template:\n", "\n", "```Python\n", "def get_roots(a, b, c):\n", " d = b**2 - 4 * a * c\n", " if ___:\n", " if ___:\n", " if ___:\n", " roots = -float('inf'), float('inf')\n", " else:\n", " roots = None\n", " else:\n", " ___\n", " elif math.isclose(d, 0):\n", " roots = ___ # repeated root\n", " else:\n", " d **= 0.5\n", " roots = ___\n", " return roots\n", "```\n", "\n", "````" ] }, { "cell_type": "code", "execution_count": 9, "id": "cdb68285", "metadata": { "code_folding": [ 0 ], "deletable": false, "editable": false, "nbgrader": { "cell_type": "code", "checksum": "5d991e44c6b5378dbe741263bcf09984", "grade": true, "grade_id": "test-degenerate", "locked": true, "points": 1, "schema_version": 3, "solution": false, "task": false }, "slideshow": { "slide_type": "skip" }, "tags": [ "hide-input", "remove-output" ] }, "outputs": [ { "ename": "NotImplementedError", "evalue": "", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mNotImplementedError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;31m# tests\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0mtest_get_roots\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0;36m1.0\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m0.0\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 3\u001b[0m \u001b[0mtest_get_roots\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m0.0\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0mtest_get_roots\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0mfloat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'inf'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mfloat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'inf'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0mtest_get_roots\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;32mNone\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m\u001b[0m in \u001b[0;36mtest_get_roots\u001b[0;34m(roots, a, b, c)\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mc\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mreal\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mc\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mimag\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 6\u001b[0;31m \u001b[0mroots_\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mget_roots\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mb\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mc\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 7\u001b[0m assert (\n\u001b[1;32m 8\u001b[0m \u001b[0mhasattr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mroots\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m\"__len__\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m\u001b[0m in \u001b[0;36mget_roots\u001b[0;34m(a, b, c)\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0md\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mb\u001b[0m \u001b[0;34m**\u001b[0m \u001b[0;36m2\u001b[0m \u001b[0;34m-\u001b[0m \u001b[0;36m4\u001b[0m \u001b[0;34m*\u001b[0m \u001b[0ma\u001b[0m \u001b[0;34m*\u001b[0m \u001b[0mc\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0;31m# YOUR CODE HERE\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 4\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mNotImplementedError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 5\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mroots\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;31mNotImplementedError\u001b[0m: " ] } ], "source": [ "# tests\n", "test_get_roots((-1.0, 0.0), 1, 1, 0)\n", "test_get_roots(0.0, 1, 0, 0)\n", "test_get_roots((-float('inf'), float('inf')), 0, 0, 0)\n", "test_get_roots(None, 0, 0, 1)\n", "test_get_roots(0.5, 0, -2, 1)\n", "test_get_roots(1.0, 1, -2, 1)" ] }, { "cell_type": "code", "execution_count": 10, "id": "f2f6f89c", "metadata": { "code_folding": [ 0 ], "deletable": false, "editable": false, "nbgrader": { "cell_type": "code", "checksum": "8ee8bbfeb16c1bf80e555537f093154d", "grade": true, "grade_id": "test_test-degenerate", "locked": true, "points": 1, "schema_version": 3, "solution": false, "task": false }, "tags": [ "remove-cell" ] }, "outputs": [], "source": [ "# hidden tests" ] }, { "cell_type": "markdown", "id": "f1182418", "metadata": {}, "source": [ "After you have complete the exercises, you can run your robust solver below:" ] }, { "cell_type": "code", "execution_count": 11, "id": "6a49dc1c", "metadata": { "code_folding": [ 0 ], "slideshow": { "slide_type": "-" }, "tags": [ "remove-output" ] }, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "aef5c25097ff4a19842a443cd947489b", "version_major": 2, "version_minor": 0 }, "text/plain": [ "interactive(children=(IntSlider(value=1, description='a', max=10, min=-10), IntSlider(value=2, description='b'…" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# quadratic equations solver\n", "@interact(a=(-10,10,1),b=(-10,10,1),c=(-10,10,1))\n", "def quadratic_equation_solver(a=1,b=2,c=1):\n", " print('Root(s):',get_roots(a,b,c))" ] }, { "cell_type": "markdown", "id": "162e7ff3", "metadata": {}, "source": [ "## Flowcharts (optional)" ] }, { "cell_type": "markdown", "id": "25ce40d8", "metadata": {}, "source": [ "Let's play a game to test your understanding of boolean expressions. Run the following program and choose your input so that 1, 2, 3 are each printed in a separate line as follows:\n", "``` \n", "1\n", "2\n", "3\n", "```" ] }, { "cell_type": "code", "execution_count": 12, "id": "6538bbe1", "metadata": { "tags": [ "remove-output" ] }, "outputs": [ { "ename": "StdinNotImplementedError", "evalue": "raw_input was called, but this frontend does not support input requests.", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mStdinNotImplementedError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0minput\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mor\u001b[0m \u001b[0minput\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m2\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0minput\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m3\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;32m~/my-conda-envs/jb/lib/python3.8/site-packages/ipykernel/kernelbase.py\u001b[0m in \u001b[0;36mraw_input\u001b[0;34m(self, prompt)\u001b[0m\n\u001b[1;32m 843\u001b[0m \"\"\"\n\u001b[1;32m 844\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_allow_stdin\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 845\u001b[0;31m raise StdinNotImplementedError(\n\u001b[0m\u001b[1;32m 846\u001b[0m \u001b[0;34m\"raw_input was called, but this frontend does not support input requests.\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 847\u001b[0m )\n", "\u001b[0;31mStdinNotImplementedError\u001b[0m: raw_input was called, but this frontend does not support input requests." ] } ], "source": [ "input(1) or input(2) and input(3)" ] }, { "cell_type": "markdown", "id": "523d3f85", "metadata": {}, "source": [ "````{hint}\n", "\n", "The following flowchart describes the [short-circuit evaluation](https://docs.python.org/3/reference/expressions.html?highlight=precedence#boolean-operations) for the boolean expression as follows:\n", "\n", "![1or2and3](images/1or2and3.svg)\n", "\n", "````" ] }, { "cell_type": "markdown", "id": "9b47ac95", "metadata": {}, "source": [ "**How to read the flowchart?**" ] }, { "cell_type": "markdown", "id": "e2927ac8", "metadata": {}, "source": [ "A flowchart uses arrows to connects a set of [annotated blocks][bb]. The rules were first specified by ANSI and later adopted in [ISO 5807][iso].\n", "\n", "[bb]: https://en.wikipedia.org/wiki/Flowchart#Building_blocks\n", "[iso]: https://webstore.ansi.org/Standards/ISO/ISO58071985" ] }, { "cell_type": "markdown", "id": "d243b088", "metadata": {}, "source": [ "For the above game, start from the first decision block at the top and choose the input appropriately to transition along the `yes` arrows." ] }, { "cell_type": "markdown", "id": "37cccfe1", "metadata": {}, "source": [ "**Why use a program flowchart?**" ] }, { "cell_type": "markdown", "id": "72ec7d45", "metadata": {}, "source": [ "A program flowchart is a powerful way of describing an algorithm quickly. Unlike a text-based programming language:\n", "- The rules governing the program flow can be shown explicitly by arrows.\n", "- The annotated graphical blocks can convey the meaning faster using visual clues." ] }, { "cell_type": "markdown", "id": "b43a1cce", "metadata": {}, "source": [ "A programmer can draft a program in flowchart without worrying about syntax (indentation, colon, ...). E.g., the above flow chart can be implemented as follows using the if statement instead of the boolean operators." ] }, { "cell_type": "code", "execution_count": 13, "id": "bf7e6714", "metadata": { "tags": [ "remove-output" ] }, "outputs": [ { "ename": "StdinNotImplementedError", "evalue": "raw_input was called, but this frontend does not support input requests.", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mStdinNotImplementedError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0minput\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0minput\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m2\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0minput\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m3\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m~/my-conda-envs/jb/lib/python3.8/site-packages/ipykernel/kernelbase.py\u001b[0m in \u001b[0;36mraw_input\u001b[0;34m(self, prompt)\u001b[0m\n\u001b[1;32m 843\u001b[0m \"\"\"\n\u001b[1;32m 844\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_allow_stdin\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 845\u001b[0;31m raise StdinNotImplementedError(\n\u001b[0m\u001b[1;32m 846\u001b[0m \u001b[0;34m\"raw_input was called, but this frontend does not support input requests.\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 847\u001b[0m )\n", "\u001b[0;31mStdinNotImplementedError\u001b[0m: raw_input was called, but this frontend does not support input requests." ] } ], "source": [ "if not input(1):\n", " if input(2):\n", " input(3)" ] }, { "cell_type": "markdown", "id": "78b80f5b", "metadata": {}, "source": [ "**How to convert the program to a flowchart automatically?**" ] }, { "cell_type": "markdown", "id": "60d2f454", "metadata": {}, "source": [ "To draw a flowchart, we can use a vector graphics editor. [Inkscape](https://inkscape.org/) is an open source software the runs in Linux/Mac/Windows. To run on mobile devices, you can run it with the desktop launcher in your jupyter server." ] }, { "cell_type": "markdown", "id": "1ad88765", "metadata": {}, "source": [ "A web application you can run without a desktop is [`ipydrawio`](https://ipydrawio.readthedocs.io/en/stable/):\n", "- In the file tab, create a file called `test.dio.svg` and double click it.\n", "- After you finished drawing the flowchart, save it and use it as an [SVG image](https://en.wikipedia.org/wiki/Scalable_Vector_Graphics)." ] }, { "cell_type": "markdown", "id": "aa59af83", "metadata": {}, "source": [ "The most convenient way, of course, is to ask python to convert a python code to a flowchart automatically. This can be done with [`pyflowchart`](https://github.com/cdfmlr/pyflowchart):" ] }, { "cell_type": "code", "execution_count": 14, "id": "a1d3d7d0", "metadata": {}, "outputs": [], "source": [ "from pyflowchart import Flowchart\n", "\n", "def code2flow(code):\n", " '''\n", " Given input code (as a string), returns the flowchart (as a string) that can be rendered by\n", " http://flowchart.js.org\n", " '''\n", " return Flowchart.from_code(code, simplify=False).flowchart()" ] }, { "cell_type": "markdown", "id": "597ae38d", "metadata": {}, "source": [ "Pass the code as a string to `code2flow`:" ] }, { "cell_type": "code", "execution_count": 15, "id": "6dc3afb5", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "cond3=>condition: if (not input(1))\n", "cond8=>condition: if input(2)\n", "sub12=>subroutine: input(3)\n", "\n", "cond3(yes)->cond8\n", "cond8(yes)->sub12\n", "\n" ] } ], "source": [ "fc = code2flow('''\n", "if not input(1):\n", " if input(2):\n", " input(3)\n", "''')\n", "print(fc)" ] }, { "cell_type": "markdown", "id": "966db20a", "metadata": {}, "source": [ "The output is a string in a [domain-specific language (DSL)][dsl] that can be [rendered here with flowchart.js][fc]. Simply overwrite a demo textbox there with the printed flowchart code above.\n", "\n", "[dsl]: https://en.wikipedia.org/wiki/Domain-specific_language\n", "[fc]: http://flowchart.js.org" ] }, { "cell_type": "markdown", "id": "a25db98c", "metadata": {}, "source": [ "**How to write a documentation with flowcharts? \n", "What about other DSL for special contents such as diagrams, equations, lists, ...?**" ] }, { "cell_type": "markdown", "id": "85801459", "metadata": {}, "source": [ "[Markdown](https://en.wikipedia.org/wiki/Markdown) is becoming popular in writing documentations. jupyter notebooks, jupyterbook, github, ... all supports markdown, but to different extents:\n", "\n", "- Jupyter notebook such as this one supports [CommonMark](https://commonmark.org).\n", "- Our [cs1302 jupyterbook](https://www.cs.cityu.edu.hk/~ccha23/cs1302book) is written in [MyST](https://myst-parser.readthedocs.io/en/latest/syntax/syntax.html) markdown.\n", "- Github uses [Github Flavored Markdown (GFM).](https://github.github.com/gfm/)\n", "\n", "Unfortunately, none of them support the flowchart code currently." ] }, { "cell_type": "markdown", "id": "bcff4b9a", "metadata": {}, "source": [ "Nevertheless, many editors such as [Typora](https://typora.io) supports advanced Markdown language with live preview. We can also extend VS Code to do the same using [Markdown Preview Enhanced](https://shd101wyy.github.io/markdown-preview-enhanced/#/) as follows:" ] }, { "cell_type": "markdown", "id": "72d1ee09", "metadata": {}, "source": [ "````{tip}\n", "\n", "You can install any extension on the VS Code interface of the JupyterHub server. To render flowchart code:\n", "\n", "1. Open `Launcher` (click on the **+** sign in the top left or press `Shift + Ctrl + L`) and click on `VS Code` to create a VSCode tab\n", "2. Click the extension tab on the left and search for *Markdown Preview Enhanced*.\n", "3. Click install and refresh the browser.\n", "4. Click the file explorer tab and create a new file say `test.md` file.\n", "5. Insert the flowchart in DSL to the `test.md` [as follows](https://shd101wyy.github.io/markdown-preview-enhanced/#/diagrams?id=flow-charts): \n", " ````Markdown\n", " ```flow\n", " cond3=>condition: if (not input(1))\n", " cond8=>condition: if input(2)\n", " sub12=>subroutine: input(3)\n", "\n", " cond3(yes)->cond8\n", " cond8(yes)->sub12\n", " ```\n", " ````\n", "6. To show the live preview, click the `open preview` button of Markdown Preview Enhanced located on the tool bar at the top right-hand corner.\n", "\n", "You can also using `drawio` in VS Code using [the extension here](https://marketplace.visualstudio.com/items?itemName=hediet.vscode-drawio).\n", "\n", "````" ] }, { "cell_type": "markdown", "id": "51794064", "metadata": {}, "source": [ "Finally, note that the flow chart does not implement how short-circuit evaluation returns values. E.g., consider entering `a` for all the inputs and see the difference in the output of the boolean expression and the code that implements the flowchart." ] }, { "cell_type": "code", "execution_count": 16, "id": "297f6b93", "metadata": { "tags": [ "remove-output" ] }, "outputs": [ { "ename": "StdinNotImplementedError", "evalue": "raw_input was called, but this frontend does not support input requests.", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mStdinNotImplementedError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0minput\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mor\u001b[0m \u001b[0minput\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m2\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0minput\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m3\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;32m~/my-conda-envs/jb/lib/python3.8/site-packages/ipykernel/kernelbase.py\u001b[0m in \u001b[0;36mraw_input\u001b[0;34m(self, prompt)\u001b[0m\n\u001b[1;32m 843\u001b[0m \"\"\"\n\u001b[1;32m 844\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_allow_stdin\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 845\u001b[0;31m raise StdinNotImplementedError(\n\u001b[0m\u001b[1;32m 846\u001b[0m \u001b[0;34m\"raw_input was called, but this frontend does not support input requests.\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 847\u001b[0m )\n", "\u001b[0;31mStdinNotImplementedError\u001b[0m: raw_input was called, but this frontend does not support input requests." ] } ], "source": [ "input(1) or input(2) and input(3)" ] }, { "cell_type": "code", "execution_count": 17, "id": "aa70d6b1", "metadata": { "tags": [ "remove-output" ] }, "outputs": [ { "ename": "StdinNotImplementedError", "evalue": "raw_input was called, but this frontend does not support input requests.", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mStdinNotImplementedError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0minput\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0minput\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m2\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0minput\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m3\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m~/my-conda-envs/jb/lib/python3.8/site-packages/ipykernel/kernelbase.py\u001b[0m in \u001b[0;36mraw_input\u001b[0;34m(self, prompt)\u001b[0m\n\u001b[1;32m 843\u001b[0m \"\"\"\n\u001b[1;32m 844\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_allow_stdin\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 845\u001b[0;31m raise StdinNotImplementedError(\n\u001b[0m\u001b[1;32m 846\u001b[0m \u001b[0;34m\"raw_input was called, but this frontend does not support input requests.\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 847\u001b[0m )\n", "\u001b[0;31mStdinNotImplementedError\u001b[0m: raw_input was called, but this frontend does not support input requests." ] } ], "source": [ "if not input(1):\n", " if input(2):\n", " input(3)" ] }, { "cell_type": "markdown", "id": "30b5387c", "metadata": {}, "source": [ "**Exercise** (Optional) Can you implement the boolean expression exactly with the same return value using only conditionals but not boolean operators?" ] }, { "cell_type": "markdown", "id": "802ac09c", "metadata": {}, "source": [ "````{hint}\n", "\n", "Consider using [conditional expression](https://docs.python.org/3/reference/expressions.html#conditional-expressions) and [assignment expression](https://docs.python.org/3/reference/expressions.html#grammar-token-assignment-expression).\n", "\n", "````" ] } ], "metadata": { "jupytext": { "text_representation": { "extension": ".md", "format_name": "myst", "format_version": 0.13, "jupytext_version": "1.10.3" } }, "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.8" }, "source_map": [ 14, 18, 23, 28, 38, 42, 52, 64, 68, 76, 80, 104, 125, 161, 181, 185, 189, 193, 201, 205, 224, 244, 267, 285, 289, 298, 307, 330, 357, 385, 403, 407, 418, 422, 431, 435, 445, 449, 456, 460, 464, 470, 474, 480, 484, 488, 494, 498, 507, 511, 518, 525, 530, 540, 544, 571, 575, 581, 587, 591 ], "widgets": { "application/vnd.jupyter.widget-state+json": { "state": { "05d851f297d54bcc845f572bfed43493": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "24bd11019ba14d9cbc8ab27226f60349": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "IntSliderModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "IntSliderModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "IntSliderView", "continuous_update": true, "description": "b", "description_tooltip": null, "disabled": false, "layout": "IPY_MODEL_2a617e88ebaa48daad8529add9f69c59", "max": 10, "min": -10, "orientation": "horizontal", "readout": true, "readout_format": "d", "step": 1, "style": "IPY_MODEL_f578a0efe4d74ccb9f5a02f438e863ac", "value": 2 } }, "2a617e88ebaa48daad8529add9f69c59": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "3a897aa1cf944bae9516e210fcac833e": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "SliderStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "SliderStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "", "handle_color": null } }, "a971635093744f17bbf304eb693ed1e7": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "aef5c25097ff4a19842a443cd947489b": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "VBoxModel", "state": { "_dom_classes": [ "widget-interact" ], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "VBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "VBoxView", "box_style": "", "children": [ "IPY_MODEL_be77fcb941b6483c808b2ec47d3dc7ae", "IPY_MODEL_24bd11019ba14d9cbc8ab27226f60349", "IPY_MODEL_dfa37433a84a4979b4daed4556d772db", "IPY_MODEL_b1800259825f46cc92090a636617e7d4" ], "layout": "IPY_MODEL_05d851f297d54bcc845f572bfed43493" } }, "b0f25bb1a59a49d6b4200e1cbbe18651": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "b1800259825f46cc92090a636617e7d4": { "model_module": "@jupyter-widgets/output", "model_module_version": "1.0.0", "model_name": "OutputModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/output", "_model_module_version": "1.0.0", "_model_name": "OutputModel", "_view_count": null, "_view_module": "@jupyter-widgets/output", "_view_module_version": "1.0.0", "_view_name": "OutputView", "layout": "IPY_MODEL_bdc21227bb61444397394f8816f38514", "msg_id": "", "outputs": [ { "ename": "NotImplementedError", "evalue": "", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mNotImplementedError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m~/my-conda-envs/jb/lib/python3.8/site-packages/ipywidgets/widgets/interaction.py\u001b[0m in \u001b[0;36mupdate\u001b[0;34m(self, *args)\u001b[0m\n\u001b[1;32m 254\u001b[0m \u001b[0mvalue\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mwidget\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_interact_value\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 255\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mwidget\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_kwarg\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mvalue\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 256\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mresult\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mf\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m**\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 257\u001b[0m \u001b[0mshow_inline_matplotlib_plots\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 258\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mauto_display\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mresult\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m\u001b[0m in \u001b[0;36mquadratic_equation_solver\u001b[0;34m(a, b, c)\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0;34m@\u001b[0m\u001b[0minteract\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0;36m10\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;36m10\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mb\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0;36m10\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;36m10\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mc\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0;36m10\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;36m10\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mquadratic_equation_solver\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mb\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m2\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mc\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 4\u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Root(s):'\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mget_roots\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mb\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mc\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;32m\u001b[0m in \u001b[0;36mget_roots\u001b[0;34m(a, b, c)\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0md\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mb\u001b[0m \u001b[0;34m**\u001b[0m \u001b[0;36m2\u001b[0m \u001b[0;34m-\u001b[0m \u001b[0;36m4\u001b[0m \u001b[0;34m*\u001b[0m \u001b[0ma\u001b[0m \u001b[0;34m*\u001b[0m \u001b[0mc\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0;31m# YOUR CODE HERE\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 4\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mNotImplementedError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 5\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mroots\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;31mNotImplementedError\u001b[0m: " ] } ] } }, "bdc21227bb61444397394f8816f38514": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "be77fcb941b6483c808b2ec47d3dc7ae": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "IntSliderModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "IntSliderModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "IntSliderView", "continuous_update": true, "description": "a", "description_tooltip": null, "disabled": false, "layout": "IPY_MODEL_a971635093744f17bbf304eb693ed1e7", "max": 10, "min": -10, "orientation": "horizontal", "readout": true, "readout_format": "d", "step": 1, "style": "IPY_MODEL_3a897aa1cf944bae9516e210fcac833e", "value": 1 } }, "dbb5f3bb567c423fa5d5604396375e71": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "SliderStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "SliderStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "", "handle_color": null } }, "dfa37433a84a4979b4daed4556d772db": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "IntSliderModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "IntSliderModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "IntSliderView", "continuous_update": true, "description": "c", "description_tooltip": null, "disabled": false, "layout": "IPY_MODEL_b0f25bb1a59a49d6b4200e1cbbe18651", "max": 10, "min": -10, "orientation": "horizontal", "readout": true, "readout_format": "d", "step": 1, "style": "IPY_MODEL_dbb5f3bb567c423fa5d5604396375e71", "value": 1 } }, "f578a0efe4d74ccb9f5a02f438e863ac": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "SliderStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "SliderStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "", "handle_color": null } } }, "version_major": 2, "version_minor": 0 } } }, "nbformat": 4, "nbformat_minor": 5 }